package cn.com.sparkle.paxos.client.net;

import java.io.Serializable;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.log4j.Logger;

import cn.com.sparkle.paxos.iomodel.protobuffmessage.PaxosMessages.GetNewsSenatorsResponse;
import cn.com.sparkle.paxos.iomodel.protobuffmessage.PaxosMessages.MessagePackage;
import cn.com.sparkle.paxos.net.CallBack;
import cn.com.sparkle.paxos.net.NetNode;
//import cn.com.sparkle.paxos.net.message.GetNewsSenatorsResponse;
import cn.com.sparkle.paxos.util.IdComparator;

public class GetNewsSenatorsCallBack implements CallBack {
	private Logger logger = Logger.getLogger(GetNewsSenatorsCallBack.class);
	public int needResponseCount;
	private ReentrantLock lock = new ReentrantLock();
	private Condition finishCondition = lock.newCondition();
	private GetNewsSenatorsResponse response;

	public GetNewsSenatorsCallBack(int needResponseCount) {
		this.needResponseCount = needResponseCount;
	}

	@Override
	public void call(NetNode nnode, MessagePackage value) {
		try {
			lock.lock();

			--needResponseCount;
			GetNewsSenatorsResponse r = value.getGetNewsSenatorsResponse();
			if (response == null) {
				response = r;
			} else {
				if (r.getVersion() > response.getVersion()
						|| (r.getVersion() == response.getVersion() && IdComparator
								.getInstance().compare(r.getMaster(),
										response.getMaster()) > 0)) {
					// r
					// .getMaster().compareTo(response.getMaster()) > 0)) {
					response = r;
				}
			}
			checkCount();
		} finally {
			lock.unlock();
		}
	}

	@Override
	public void fail(NetNode nnode) {
		try {
			lock.lock();
			--needResponseCount;
			checkCount();
		} finally {
			lock.unlock();
		}
	}

	private void checkCount() {
		try {
			lock.lock();
			if (needResponseCount == 0) {
				finishCondition.signal();
			}
		} finally {
			lock.unlock();
		}

	}

	public void waitFinish() throws InterruptedException {
		try {
			lock.lock();
			if (needResponseCount != 0) {
				finishCondition.await();
			}
		} finally {
			lock.unlock();
		}
	}

	public GetNewsSenatorsResponse getResponse() {
		return response;
	}
}
